#pragma once
#include "PlayerItem.h"
namespace catan
{
	class Building : public PlayerItem
	{
	public:
		Building()
		{
		}

		virtual ~Building()
		{

		}
		Handle<BuildPoint> GetBuildPoint() const { return mBuildPoint; }
		void SetBuildPoint(Handle<BuildPoint> val) { mBuildPoint = val; }
		virtual int GetResourceCardHarvestNum() = 0;
	protected:
		Handle<BuildPoint> mBuildPoint;
	public:
		template<class Serializer>
		void serialize(Serializer & s, const unsigned int version)
		{
			s & boost::serialization::base_object<PlayerItem>(*this);
			s & mBuildPoint ;
		}
	};

	class House : public Building
	{
	public:
		House(void)
		{
		}
		~House(void)
		{

		}

		static FieldResourceTypes GetBuyCards()
		{
			FieldResourceTypes p;
			p.push_back(FieldResourceType::Brick);
			p.push_back(FieldResourceType::Wood);
			p.push_back(FieldResourceType::Grain);
			p.push_back(FieldResourceType::Sheep);
			return p;
		}
		virtual int GetResourceCardHarvestNum() {return 1;}
		static int GetVictoryPoint() {return 1;}


	};

	class Settlement : public Building
	{
	public:
		Settlement(void)
		{
		}
		~Settlement(void)
		{

		}
		static FieldResourceTypes GetBuyCards()
		{
			FieldResourceTypes p;
			p.push_back(FieldResourceType::Grain);
			p.push_back(FieldResourceType::Grain);
			p.push_back(FieldResourceType::Grain);
			p.push_back(FieldResourceType::Iron);
			p.push_back(FieldResourceType::Iron);
			return p;
		}
		static int GetVictoryPoint() {return 2;}
		virtual int GetResourceCardHarvestNum() {return 2;}

	};

	template <class _Ty>
	struct Buildings
	{
		Buildings() : mUseNum(0) {}
		void DeleteAll()
		{
			for (_Tys::iterator it(mTys.begin());
				it != mTys.end(); ++it)
			{
				delete (*it);
			}
		}
		void SetColor(PlayerColor::Enum color)
		{
			for (_Tys::iterator it(mTys.begin());
				it != mTys.end(); ++it)
			{
				(*it)->SetColor(color);
			}
		}
		void Add(Handle<_Ty> ty)
		{
			mTys.push_back(ty);
		}

		size_t GetUseNum()
		{
			return mUseNum;
		}

		bool Empty()
		{
			return mTys.size() < mUseNum;
		}

		int Size() 
		{
			return mTys.size();
		}

		Handle<_Ty> Use()
		{
			if (mUseNum < mTys.size())
			{
				mTys[mUseNum]->SetBuilt(true);
				return mTys[mUseNum++];
			}
			return Handle<_Ty>();
		}

		void Recycle(Handle<_Ty> ty)
		{
			_Tys::iterator it = std::find(mTys.begin(), mTys.end(), ty);
			if (it == mTys.end())
			{
				LogError(_T("sth wrong"));
				return ;
			}
			std::sort(mTys.begin(), mTys.end(), Cmp);
		}

		static bool Cmp(Handle<_Ty> lhs, Handle<_Ty> rhs)
		{
			return int(lhs->HasBuilt()) < int(rhs->HasBuilt());
		}
		typedef std::vector<Handle<_Ty>> _Tys;
		 _Tys& GetVector()  {return mTys;}

		_Tys mTys;
		size_t mUseNum;

	public:
		template<class Serializer>
		void serialize(Serializer & s, const unsigned int version)
		{
			s & mTys;
			s & mUseNum ;
		}
	};
}	
